package com.nanyang.tms.manager.waybill.handler;

import com.nanyang.common.core.annotation.SystemLog;
import com.nanyang.common.core.annotation.SystemMessage;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.nanyang.common.core.flow.context.TransHandlerContext;
import com.nanyang.common.core.flow.handler.AbstractTransHandler;
import com.nanyang.common.tool.utils.uuid.GlobalIdGeneratorUtil;
import com.nanyang.tms.common.contstant.TmsSerializeConstant;
import com.nanyang.tms.common.dict.TmsExceptionEnum;
import com.nanyang.tms.common.exception.TmsManagerException;
import com.nanyang.tms.common.util.TmsExceptionUtil;
import com.nanyang.tms.dao.forecast.ForecastDao;
import com.nanyang.tms.dao.receipt.ReceiptBillDao;
import com.nanyang.tms.dao.waybill.WaybillDao;
import com.nanyang.tms.dao.waybill.WaybillReceiptDao;
import com.nanyang.tms.dao.waybill.WaybillReceiptVolumeDao;
import com.nanyang.tms.domain.forecast.ForecastDetailVO;
import com.nanyang.tms.domain.forecast.context.CalculateFreightContext;
import com.nanyang.tms.domain.forecast.context.CalculateWeightContext;
import com.nanyang.tms.domain.forecast.context.CalculateWeightVolumeContext;
import com.nanyang.tms.domain.receipt.ReceiptBillVO;
import com.nanyang.tms.domain.waybill.WaybillDO;
import com.nanyang.tms.domain.waybill.WaybillReceiptDO;
import com.nanyang.tms.domain.waybill.WaybillReceiptVolumeDO;
import com.nanyang.tms.domain.waybill.context.SaveWaybillReceiptContext;

@Component
public class SaveWaybillReceiptHandler extends AbstractTransHandler {
	@Autowired
	private WaybillDao waybillDao;
	@Autowired
	private WaybillReceiptDao waybillReceiptDao;
	@Autowired
	private WaybillReceiptVolumeDao waybillReceiptVolumeDao;
	@Autowired
	private ForecastDao forecastDao;
	@Autowired
	private ReceiptBillDao receiptBillDao;
	@Autowired
	private GlobalIdGeneratorUtil globalIdGeneratorUtil;

	@Override
	public boolean isAsync() {
		return false;
	}
	@SystemMessage(messageType=SystemMessage.MessageType.SERVICE,template="receiptAddMsg")
	@SystemLog(module =SystemLog.Module.RECEIPT,template="receiptAddLog")
	@Override
	public boolean handle(TransHandlerContext context) {
		SaveWaybillReceiptContext saveWaybillReceiptContext = (SaveWaybillReceiptContext) context
				.getInnerContext(SaveWaybillReceiptContext.class);
		CalculateWeightContext calculateWeightContext = (CalculateWeightContext) context
				.getInnerContext(CalculateWeightContext.class);
		CalculateFreightContext calculateFreightContext = (CalculateFreightContext) context
				.getInnerContext(CalculateFreightContext.class);
		try {
			ForecastDetailVO forecastDetail = forecastDao.getForecastDetail(saveWaybillReceiptContext.getSupplierNo());
			if(ObjectUtils.isEmpty(forecastDetail)){
				throw new TmsManagerException(TmsExceptionEnum.FORECAST_IS_NOT_EXIST.getCode(), TmsExceptionEnum.FORECAST_IS_NOT_EXIST.getMessage());
			}
			if(!forecastDetail.getCountyCode().equals(calculateWeightContext.getCountyCode())
				|| !forecastDetail.getProvinceCode().equals(calculateWeightContext.getCityCode())
				|| !forecastDetail.getCompanyCode().equals(calculateFreightContext.getCompanyCode())
				|| !forecastDetail.getCargoTypeCode().equals(calculateWeightContext.getCargoTypeCode())
				|| !forecastDetail.getSaleProductCode().equals(calculateWeightContext.getSaleProductCode())){
				throw new TmsManagerException(TmsExceptionEnum.FORECAST_IS_NOT_EXIST.getCode(), TmsExceptionEnum.FORECAST_IS_NOT_EXIST.getMessage());
			}
			ReceiptBillVO receiptBillVO = receiptBillDao.getReceiptBillByCode(saveWaybillReceiptContext.getReceiptCode());
			if(ObjectUtils.isEmpty(receiptBillVO)){
				throw new TmsManagerException(TmsExceptionEnum.RECEIPT_IS_NOT_EXIST.getCode(), TmsExceptionEnum.RECEIPT_IS_NOT_EXIST.getMessage());
			}
			String nextSeq = TmsSerializeConstant.WAYBILL_KEY + globalIdGeneratorUtil
					.getNextSeq(TmsSerializeConstant.WAYBILL_SEQ_KEY, TmsSerializeConstant.SEQ_INCRBY);
			
			waybillDao.insert(bulidWaybill(forecastDetail, saveWaybillReceiptContext, nextSeq));
			waybillReceiptDao.insert(bulidWaybillReceipt(forecastDetail, receiptBillVO, saveWaybillReceiptContext,
					calculateWeightContext, nextSeq));
			int i=1;
			for (CalculateWeightVolumeContext calculateWeightVolumeContext : calculateWeightContext
					.getCalculateWeightVolumeContexts()) {
				
				waybillReceiptVolumeDao.insert(bulidWaybillReceiptVolume(forecastDetail, calculateWeightVolumeContext, i,
						saveWaybillReceiptContext, nextSeq));
				i++;
			}
			saveWaybillReceiptContext.setWaybillCode(nextSeq);
			saveWaybillReceiptContext.setForecastCode(forecastDetail.getForecastCode());
			saveWaybillReceiptContext.setFrozenAmount(forecastDetail.getAmount());
			saveWaybillReceiptContext.setAddress(receiptBillVO.getAddress());
			saveWaybillReceiptContext.setReceiptTime(receiptBillVO.getReceiptTime());
		} catch (Exception e) {
			throw TmsExceptionUtil.wrapException(e);
		}
		return true;
	}

	private WaybillDO bulidWaybill(ForecastDetailVO forecastDetail, SaveWaybillReceiptContext saveWaybillReceiptContext,
			String nextSeq) {
		WaybillDO waybillDO = WaybillDO.builder().cityCode(forecastDetail.getProvinceCode())
				.cityName(forecastDetail.getProvince()).companyCode(forecastDetail.getCompanyCode())
				.companyName(forecastDetail.getCompanyName()).countyCode(forecastDetail.getCountyCode())
				.countyName(forecastDetail.getCountyName()).customerNo(forecastDetail.getCustomerNo())
				.supplierNo(saveWaybillReceiptContext.getSupplierNo()).totalNum(saveWaybillReceiptContext.getTotalNum())
				.waybillType(0).waybillCode(nextSeq).zipCode(forecastDetail.getZipCode()).build();
		waybillDO.setIp(saveWaybillReceiptContext.getIp());
		waybillDO.setGmtCreatePin(saveWaybillReceiptContext.getPin());
		waybillDO.setGmtModifiedPin(saveWaybillReceiptContext.getPin());
		return waybillDO;
	}

	private WaybillReceiptDO bulidWaybillReceipt(ForecastDetailVO forecastDetail, ReceiptBillVO receiptBillVO,
			SaveWaybillReceiptContext saveWaybillReceiptContext, CalculateWeightContext calculateWeightContext,
			String nextSeq) {
		WaybillReceiptDO waybillReceiptDO = WaybillReceiptDO.builder()
				.waybillReceiptCode(TmsSerializeConstant.WAYBILL_RECEIPT_KEY + globalIdGeneratorUtil
						.getNextSeq(TmsSerializeConstant.WAYBILL_RECEIPT_SEQ_KEY, TmsSerializeConstant.SEQ_INCRBY))
				.waybillCode(nextSeq).companyCode(forecastDetail.getCompanyCode())
				.companyName(forecastDetail.getCompanyName()).saleProductCode(forecastDetail.getSaleProductCode())
				.saleProductName(forecastDetail.getSaleProductName())
				.totalChargeWeight(calculateWeightContext.getTotalChargeWeight())
				.totalWeight(calculateWeightContext.getTotalWeight())
				.totalVolumeWeight(calculateWeightContext.getTotalVolumeWeight())
				.totalPieceChargeWeight(calculateWeightContext.getTotalPrieceChargeWeight())
				.customerWeight(forecastDetail.getWeight()).receiptVolume(calculateWeightContext.getReceiptVolume())
				.cargoTypeCode(forecastDetail.getCargoTypeCode()).cargoTypeName(forecastDetail.getCargoTypeName())
				.address(receiptBillVO.getAddress()).operator(receiptBillVO.getOperator()).build();
		waybillReceiptDO.setIp(saveWaybillReceiptContext.getIp());
		waybillReceiptDO.setGmtCreatePin(saveWaybillReceiptContext.getPin());
		waybillReceiptDO.setGmtModifiedPin(saveWaybillReceiptContext.getPin());
		return waybillReceiptDO;
	}

	private WaybillReceiptVolumeDO bulidWaybillReceiptVolume(ForecastDetailVO forecastDetail,
			CalculateWeightVolumeContext calculateWeightVolumeContext, int i,
			SaveWaybillReceiptContext saveWaybillReceiptContext, String nextSeq) {
		WaybillReceiptVolumeDO waybillReceiptVolumeDO = WaybillReceiptVolumeDO.builder()
				.receiptVolumeCode(TmsSerializeConstant.WAYBILL_RECEIPT_KEY + globalIdGeneratorUtil
						.getNextSeq(TmsSerializeConstant.WAYBILL_RECEIPT_SEQ_KEY, TmsSerializeConstant.SEQ_INCRBY))
				.waybillCode(nextSeq).companyCode(forecastDetail.getCompanyCode())
				.supplierNo(saveWaybillReceiptContext.getSupplierNo())
				.supplierSubNo(saveWaybillReceiptContext.getSupplierNo() + "-" + i)
				.weight(calculateWeightVolumeContext.getWeight()).length(calculateWeightVolumeContext.getLength())
				.width(calculateWeightVolumeContext.getWidth()).height(calculateWeightVolumeContext.getHeight())
				.unitVolumeWeight(calculateWeightVolumeContext.getUnitVolumeWeight())
				.unitVolume(calculateWeightVolumeContext.getUnitVolume())
				.unitChargeWeight(calculateWeightVolumeContext.getUnitChargeWeight())
				.girth(calculateWeightVolumeContext.getGirth()).build();
		waybillReceiptVolumeDO.setIp(saveWaybillReceiptContext.getIp());
		waybillReceiptVolumeDO.setGmtCreatePin(saveWaybillReceiptContext.getPin());
		waybillReceiptVolumeDO.setGmtModifiedPin(saveWaybillReceiptContext.getPin());
		return waybillReceiptVolumeDO;
	}

}
